{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "361e8083",
   "metadata": {},
   "source": [
    "* 记录人：莫秀芳\n",
    "* 时间：2021-11-29\n",
    "* week14\n",
    "* 学习线上资源：\n",
    "[python官方文档](https://www.python.org/)  \n",
    "[函数的定义](https://www.cnblogs.com/xuzhichao/p/11570285.html)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "d57aa01e",
   "metadata": {},
   "source": [
    "# 本周学习目标\n",
    "> 1.函数的定义  \n",
    "> 2.函数的使用  \n",
    "> 3.函数的参数 "
   ]
  },
  {
   "cell_type": "markdown",
   "id": "558c4b65",
   "metadata": {},
   "source": [
    "# 函数的定义"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "cece07b2",
   "metadata": {},
   "source": [
    "* 定义一个函数的一般步骤"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 47,
   "id": "ff0cd5ce",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 1 2 3 5 8 \n"
     ]
    }
   ],
   "source": [
    "a, b = 0, 1\n",
    "while a < 10:\n",
    "    print(a, end=' ') # 0  1  1 2 ...\n",
    "    a, b = b, a+b # a = 1  a = 1  b = 2  a = 2 b = 3\n",
    "print()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "id": "29ca15ed",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 1 2 3 5 8 13 21 34 \n"
     ]
    }
   ],
   "source": [
    "a, b = 0, 1\n",
    "while a < 50:\n",
    "    print(a, end=' ') # 0  1  1 2 ...\n",
    "    a, b = b, a+b # a = 1  a = 1  b = 2  a = 2 b = 3\n",
    "print()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
   "id": "2a84699e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 1 2 3 5 8 13 21 34 \n"
     ]
    }
   ],
   "source": [
    "a, b = 0, 1\n",
    "while a < 50:\n",
    "    print(a, end=' ') # 0  1  1 2 ...\n",
    "    a, b = b, a+b # a = 1  a = 1  b = 2  a = 2 b = 3\n",
    "print()\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "id": "e5263875",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0 1 1 2 3 5 8 13 21 34 55 89 \n"
     ]
    }
   ],
   "source": [
    "a, b = 0, 1\n",
    "while a < 100:\n",
    "    print(a, end=' ') # 0  1  1 2 ...\n",
    "    a, b = b, a+b # a = 1  a = 1  b = 2  a = 2 b = 3\n",
    "print()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "8d48422f",
   "metadata": {},
   "outputs": [],
   "source": [
    " # ......我想重复使用某一个功能（避免重复造轮子）\n",
    "# .....使用的人可以不懂代码，只要会调用函数即可 Function_name()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "62e94ef3",
   "metadata": {},
   "source": [
    "> 1.定义函数的一般方法：\n",
    "```\n",
    "def function_name(): # 1.function_name 遵循变量定义的规则 区别数学函数==> f(x) python的函数可以自定义名称 \n",
    "  \"\"\"函数的注释\"\"\" # 2.函数的注释可以和使用者交流\n",
    "  函数体        # 3.函数体要和定义函数保持一定的tab缩进\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9db8706d",
   "metadata": {},
   "source": [
    "原括号必不可少，即使是空括号，也必不可少！！"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "b444e53a",
   "metadata": {},
   "outputs": [],
   "source": [
    "def fib(n):   # write Fibonacci series up to n\n",
    "    \"\"\"Print a Fibonacci series up to n.\"\"\"\n",
    "    a,b = 0,1\n",
    "    while a < n:\n",
    "        print(a,end='') # 0 1 1 2 ...\n",
    "        a,b = b,a+b # a = 1 a = 1 b = 2 a = 2 b = 3\n",
    "        print()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "078129f5",
   "metadata": {},
   "source": [
    "# 函数的使用"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "b3b35f57",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "1\n",
      "1\n",
      "2\n",
      "3\n",
      "5\n",
      "8\n"
     ]
    }
   ],
   "source": [
    "fib(10)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "f976498e",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "1\n",
      "1\n"
     ]
    }
   ],
   "source": [
    "fib(2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 62,
   "id": "c83d3fcd",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0\n",
      "1\n",
      "1\n",
      "2\n",
      "3\n",
      "5\n",
      "8\n",
      "13\n",
      "21\n",
      "34\n",
      "55\n",
      "89\n"
     ]
    }
   ],
   "source": [
    "fib(100)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "f00d7101",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 1.请大家写一个函数 实现 hello world\n",
    "# 2. 请大家写一个函数 实现 hello username"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "9802e843",
   "metadata": {},
   "outputs": [],
   "source": [
    "def hello():\n",
    "    \"\"\"打印你好，世界\"\"\"\n",
    "    print(\"hello,world\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "aebe63b7",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello,world\n"
     ]
    }
   ],
   "source": [
    "hello()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "c9eacd0c",
   "metadata": {},
   "outputs": [],
   "source": [
    "def hello_user(username):\n",
    "    \"\"\"打印，你好，许智超同学~\"\"\"\n",
    "    print(\"你好，\"+ username.title()+\"同学~\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "d045a4dd",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "你好，许智超同学~\n"
     ]
    }
   ],
   "source": [
    "hello_user(\"许智超\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "25491cef",
   "metadata": {},
   "outputs": [],
   "source": [
    "* 思考: 函数是否必须有参数?\n",
    "* 注意:"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "c15adbae",
   "metadata": {},
   "source": [
    "## 3.函数的参数\n",
    "> 1.形式参数：定义函数时，写在function_name 括号里面的参数\n",
    ">> 1.在定义函数时,形式参数不占用空间\n",
    "\n",
    "> 2.实际参数\n",
    ">> A.调用函数时,写在function_name 括号里面的参数  \n",
    ">> B. 在使用函数时,形式参数 被 分配空间,变为实际参数"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "73dc41f1",
   "metadata": {},
   "source": [
    "定义函数,函数可以有多个函数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "54aa13d0",
   "metadata": {},
   "outputs": [],
   "source": [
    "def describe_pet(animal_type,pet_name): # animal_type,pet_name 是形式参数 简称 形参\n",
    "    \"\"\"显示宠物信息\"\"\"\n",
    "    print(\"\\nI have a\"+ animal_type + \".\")\n",
    "    print(\"My\"+ animal_type + \"'s name is'\"+pet_name.title() + \".\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bdd9fe7d",
   "metadata": {},
   "source": [
    "* 当函数具有多个参数时\n",
    "\n",
    "> 1.位置参数  \n",
    ">> 1.形式参数有先后顺序,函数调用过程应考虑参数的先后顺序,避免出现顺序错误的笑话  \n",
    ">> 2.调用函数过程中要考虑形式参数的个数  \n",
    "> 2.关键字参数  \n",
    ">> 1.调用函数时,通过赋值的方式传递给定义好的形参变量数据  \n",
    ">> 2.关键字参数不考虑先后顺序,因为是指定变量赋值的(这也是它的优势所在)  \n",
    "> 3.默认参数\n",
    ">> 1.在形式参数中,提前预先设置一个用户可能使用的参数值  \n",
    ">> 2.用户在使用/调用函数时,可以省略不给默认参数赋值  \n",
    ">> 3.用户给默认参数赋值,将替换默认参数的值  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "9b9585f5",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have adog.\n",
      "Mydog's name is'许智超.\n"
     ]
    }
   ],
   "source": [
    "describe_pet(\"dog\",\"许智超\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "3ab3b849",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have adog.\n",
      "Mydog's name is'豆豆.\n"
     ]
    }
   ],
   "source": [
    "# 在使用 describe_pet()函数时 需要考虑参数的位置,从而进行参数数据的输入(实参的调用)\n",
    "# 位置参数:\n",
    "describe_pet(\"dog\",\"豆豆\")# 要根据 形式参数的位置先后顺序 先写animal_type,再写pet_name"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "4d541672",
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "describe_pet() missing 2 required positional arguments: 'animal_type' and 'pet_name'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-28-17751bc0b2be>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mdescribe_pet\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;31m# 错误示范\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m: describe_pet() missing 2 required positional arguments: 'animal_type' and 'pet_name'"
     ]
    }
   ],
   "source": [
    "describe_pet() # 错误示范"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "id": "50524390",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have adog.\n",
      "Mydog's name is'智超.\n"
     ]
    }
   ],
   "source": [
    "# 关键字参数使用\n",
    "describe_pet(pet_name=\"智超\",animal_type=\"dog\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 44,
   "id": "2c8b0846",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 默认参数\n",
    "def describe_pet(pet_name,animal_type=\"dog\"): # animal_type,pet_name 是形式参数 形参\n",
    "    \"\"\"显示宠物信息\"\"\"\n",
    "    print(\"\\nI have a \" + animal_type + \".\")\n",
    "    print(\"My \" + animal_type + \"'s name is \"+pet_name.title() + \".\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "id": "6927d0b0",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "I have a许智超.\n",
      "My许智超's name is'Dog.\n"
     ]
    }
   ],
   "source": [
    "describe_pet(\"许智超\",\"dog\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "id": "c3be47ee",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hello\n",
      "hello\n"
     ]
    }
   ],
   "source": [
    "print(\"hello\",'\\n',\"hello\",sep='')\n",
    "# print(\"hello\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "39ecd3d3",
   "metadata": {},
   "source": [
    "默认参数可以修改的"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "id": "34931cc3",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Help on built-in function print in module builtins:\n",
      "\n",
      "print(...)\n",
      "    print(value, ..., sep=' ', end='\\n', file=sys.stdout, flush=False)\n",
      "    \n",
      "    Prints the values to a stream, or to sys.stdout by default.\n",
      "    Optional keyword arguments:\n",
      "    file:  a file-like object (stream); defaults to the current sys.stdout.\n",
      "    sep:   string inserted between values, default a space.\n",
      "    end:   string appended after the last value, default a newline.\n",
      "    flush: whether to forcibly flush the stream.\n",
      "\n"
     ]
    }
   ],
   "source": [
    "help(print)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "bc7dfe23",
   "metadata": {},
   "source": [
    "------------\n",
    "参数使用过程中的思考与问题:  \n",
    "> 1.思考:关键字参数(调用函数) 和 位置参数(调用函数) 是否可以一起使用? (可以)     \n",
    ">> 1.positional argument follows keyword argument(位置参数<font style=\"color:red\">均</font>要放在关键字参数前面)  \n",
    ">> 2. test1() got multiple values for argument 'x'(映射,不能出现 multiple vulues(多重值))  \n",
    "> 2. 定义函数:默认参数(定义函数)和非默认参数(定义函数)的先后关系   \n",
    ">> 1.non-default argument follows default argument(非默认参数<font style=\"color:red\">均</font>要放在默认参数前面)  \n",
    "    \n",
    "------------\n",
    "* 以下为测试代码:\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 56,
   "id": "688cc3e5",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 案例1:\n",
    "def testl(x,y,z):\n",
    "    \"\"\"打印x,y,z的值\"\"\"\n",
    "    print(x)\n",
    "    print(y)\n",
    "    print(z)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 58,
   "id": "923ae906",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "3\n",
      "4\n"
     ]
    }
   ],
   "source": [
    "testl(x=2,y=3,z=4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "id": "3498e635",
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'testl' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-54-4c652e9acffb>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mtestl\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0my\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m3\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mz\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m4\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m: name 'testl' is not defined"
     ]
    }
   ],
   "source": [
    "testl(2,y=3,z=4)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 60,
   "id": "7ea6d7fc",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "2\n",
      "3\n",
      "4\n"
     ]
    }
   ],
   "source": [
    "testl(2,z=4,y=3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 61,
   "id": "f299d53e",
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "testl() got multiple values for argument 'x'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-61-9c6c10e0ed4d>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mtestl\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mx\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m3\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0my\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m: testl() got multiple values for argument 'x'"
     ]
    }
   ],
   "source": [
    "testl(2,x=3,y=1)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 69,
   "id": "47468d1a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 案例2：\n",
    "def test1(x,z,y=3):\n",
    "    \"\"\"打印x,y,z的值\"\"\"\n",
    "    print(x)\n",
    "    print(y)\n",
    "    print(z)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "2a8e9541",
   "metadata": {},
   "source": [
    "## 4.课本练习实践\n",
    "> 1.请大家总结函数的优势函数与模块  \n",
    "> 2.预习课本第四章的  \n",
    ">> 1.完成课本元音字母实践  \n",
    ">> 2.浏览模块,创建模块和调用模块,了解PEP 8 python国际代码标准"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 65,
   "id": "46ee2051",
   "metadata": {},
   "outputs": [],
   "source": [
    "def search4vowels(word):\n",
    "    \"\"\"判断输入文本出现的元音字母有哪些\"\"\"\n",
    "    vowels = set(\"aeiou\")\n",
    "    word = set(word)\n",
    "    print(vowels & word)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 66,
   "id": "ded2b685",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'e', 'a'}\n"
     ]
    }
   ],
   "source": [
    "search4vowels(\"bfhdfbhjrea\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 67,
   "id": "3e1c5ddc",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'e', 'a', 'i'}\n"
     ]
    }
   ],
   "source": [
    "search4vowels(\"bfhdfbhjreai\")"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "93a8dc26",
   "metadata": {},
   "source": [
    "不懂就看这里  [许智超的gitee(https://gitee.com/xzhichao/python/blob/master/jupyter_projects/week14_%E5%91%A8%E4%B8%80%E4%B8%8B%E5%8D%88%E7%8F%AD/week14_%E5%87%BD%E6%95%B0%E4%B8%8E%E6%A8%A1%E5%9D%97.ipynb)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "1535997f",
   "metadata": {},
   "source": [
    "关键字参数的顺序并不重要.任何参数不能多次接受一个值"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "fce06e9b",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
